Option Explicit On

Imports System.Data.SqlClient
Imports System.Diagnostics

Imports System.IO
Imports System.Runtime.Serialization
Imports System.Runtime.Serialization.Formatters.Binary
Imports C3I.CodegenTools
Imports System.ComponentModel

Public Class frmMainApp

    Dim columnDictionary As Dictionary(Of String, PropertyValue), conditionArray As BindingList(Of Condition)
    Dim isNewRow As Boolean, originalValue As String, propertyDict As New Dictionary(Of String, Control)
    Dim oldValue As String

    Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
 
        mainForm = Me
        Me.Text = My.MyProject.Application.Info.Title

        PopulateGenericFields()

        dgvPropCustom.AutoGenerateColumns = False

        AddColumn("PropertyID", dgvPropCustom, New DataGridViewComboBoxColumn, New String() {""}, 150, "Name")
        AddColumn("Value", dgvPropCustom, New DataGridViewTextBoxColumn, Nothing, 150, "New ID")
        AddColumn("Type", dgvPropCustom, New DataGridViewTextBoxColumn, Nothing, 250, "Label")


        PopulateToolTips(tabColumnInfo, True)
        PopulateToolTips(tabColumnInfo2, True)
        PopulateToolTips(pnlTableInfo, True)
        PopulateToolTips(TabPage3, False)
        PopulateToolTips(pnlDatabaseInfo, True)

        Dim TTIP As New ToolTip()
        TTIP.SetToolTip(txtFieldName, "FieldName")
        TTIP.SetToolTip(txtGenericType, "BaseDataType")
        TTIP.SetToolTip(txtBaseDataType, "GenericType")

        TTIP.SetToolTip(chkIgnore, "Ignore")
        TTIP.SetToolTip(chkKey, "IsPrimaryKey")
        TTIP.SetToolTip(chkColForeignKey, "IsForeignKey")
        TTIP.SetToolTip(chkIsVirtualField, "IsVirtualField")

        TTIP.SetToolTip(txtServerName, "ServerName")
        TTIP.SetToolTip(txtServerUserID, "ServerUserName")
        TTIP.SetToolTip(txtServerPassword, "ServerPassword")

        TTIP.SetToolTip(txtTableName, "TableName")
        TTIP.SetToolTip(txtTableDescription, "TableDescription")

        TTIP.SetToolTip(txtDataSourceName, "DataSourceName")
        TTIP.SetToolTip(txtDBConnectionString, "DBConnectionString")

        AddHandler txtFlagLabel1.TextChanged, AddressOf Me.txtFlagLabel_TextChanged
        AddHandler txtFlagLabel2.TextChanged, AddressOf Me.txtFlagLabel_TextChanged
        AddHandler txtFlagLabel3.TextChanged, AddressOf Me.txtFlagLabel_TextChanged
        AddHandler txtFlagLabel4.TextChanged, AddressOf Me.txtFlagLabel_TextChanged
        AddHandler txtFlagLabel5.TextChanged, AddressOf Me.txtFlagLabel_TextChanged
        AddHandler txtFlagLabel6.TextChanged, AddressOf Me.txtFlagLabel_TextChanged
        AddHandler txtFlagLabel7.TextChanged, AddressOf Me.txtFlagLabel_TextChanged
        AddHandler txtFlagLabel8.TextChanged, AddressOf Me.txtFlagLabel_TextChanged
        AddHandler txtFlagLabel9.TextChanged, AddressOf Me.txtFlagLabel_TextChanged
        AddHandler txtFlagLabel10.TextChanged, AddressOf Me.txtFlagLabel_TextChanged
        AddHandler txtFlagLabel11.TextChanged, AddressOf Me.txtFlagLabel_TextChanged
        AddHandler txtFlagLabel12.TextChanged, AddressOf Me.txtFlagLabel_TextChanged
        AddHandler txtFlagLabel13.TextChanged, AddressOf Me.txtFlagLabel_TextChanged
        AddHandler txtFlagLabel14.TextChanged, AddressOf Me.txtFlagLabel_TextChanged
        AddHandler txtFlagLabel15.TextChanged, AddressOf Me.txtFlagLabel_TextChanged

        AddHandler txtTableFlagLabel1.TextChanged, AddressOf Me.txtFlagLabel_TextChanged
        AddHandler txtTableFlagLabel2.TextChanged, AddressOf Me.txtFlagLabel_TextChanged
        AddHandler txtTableFlagLabel3.TextChanged, AddressOf Me.txtFlagLabel_TextChanged
        AddHandler txtTableFlagLabel4.TextChanged, AddressOf Me.txtFlagLabel_TextChanged
        AddHandler txtTableFlagLabel5.TextChanged, AddressOf Me.txtFlagLabel_TextChanged
        AddHandler txtTableFlagLabel6.TextChanged, AddressOf Me.txtFlagLabel_TextChanged
        AddHandler txtTableFlagLabel7.TextChanged, AddressOf Me.txtFlagLabel_TextChanged
        AddHandler txtTableFlagLabel8.TextChanged, AddressOf Me.txtFlagLabel_TextChanged
        AddHandler txtTableFlagLabel9.TextChanged, AddressOf Me.txtFlagLabel_TextChanged
        AddHandler txtTableFlagLabel10.TextChanged, AddressOf Me.txtFlagLabel_TextChanged

        AddHandler txtFlagDescription1.TextChanged, AddressOf Me.txtFlagDescription_TextChanged
        AddHandler txtFlagDescription2.TextChanged, AddressOf Me.txtFlagDescription_TextChanged
        AddHandler txtFlagDescription3.TextChanged, AddressOf Me.txtFlagDescription_TextChanged
        AddHandler txtFlagDescription4.TextChanged, AddressOf Me.txtFlagDescription_TextChanged
        AddHandler txtFlagDescription5.TextChanged, AddressOf Me.txtFlagDescription_TextChanged
        AddHandler txtFlagDescription6.TextChanged, AddressOf Me.txtFlagDescription_TextChanged
        AddHandler txtFlagDescription7.TextChanged, AddressOf Me.txtFlagDescription_TextChanged
        AddHandler txtFlagDescription8.TextChanged, AddressOf Me.txtFlagDescription_TextChanged
        AddHandler txtFlagDescription9.TextChanged, AddressOf Me.txtFlagDescription_TextChanged
        AddHandler txtFlagDescription10.TextChanged, AddressOf Me.txtFlagDescription_TextChanged
        AddHandler txtFlagDescription11.TextChanged, AddressOf Me.txtFlagDescription_TextChanged
        AddHandler txtFlagDescription12.TextChanged, AddressOf Me.txtFlagDescription_TextChanged
        AddHandler txtFlagDescription13.TextChanged, AddressOf Me.txtFlagDescription_TextChanged
        AddHandler txtFlagDescription14.TextChanged, AddressOf Me.txtFlagDescription_TextChanged
        AddHandler txtFlagDescription15.TextChanged, AddressOf Me.txtFlagDescription_TextChanged

        AddHandler txtTableFlagDescription1.TextChanged, AddressOf Me.txtFlagDescription_TextChanged
        AddHandler txtTableFlagDescription2.TextChanged, AddressOf Me.txtFlagDescription_TextChanged
        AddHandler txtTableFlagDescription3.TextChanged, AddressOf Me.txtFlagDescription_TextChanged
        AddHandler txtTableFlagDescription4.TextChanged, AddressOf Me.txtFlagDescription_TextChanged
        AddHandler txtTableFlagDescription5.TextChanged, AddressOf Me.txtFlagDescription_TextChanged
        AddHandler txtTableFlagDescription6.TextChanged, AddressOf Me.txtFlagDescription_TextChanged
        AddHandler txtTableFlagDescription7.TextChanged, AddressOf Me.txtFlagDescription_TextChanged
        AddHandler txtTableFlagDescription8.TextChanged, AddressOf Me.txtFlagDescription_TextChanged
        AddHandler txtTableFlagDescription9.TextChanged, AddressOf Me.txtFlagDescription_TextChanged
        AddHandler txtTableFlagDescription10.TextChanged, AddressOf Me.txtFlagDescription_TextChanged

        AddHandler txtFunctionCode.TextChanged, AddressOf Me.txtFlagDescription_TextChanged

        AddHandler txtMessage1.TextChanged, AddressOf txtTableTextChanged_TextChanged
        AddHandler txtMessage2.TextChanged, AddressOf txtTableTextChanged_TextChanged
        AddHandler txtMessage3.TextChanged, AddressOf txtTableTextChanged_TextChanged
        AddHandler txtMessage4.TextChanged, AddressOf txtTableTextChanged_TextChanged

        AddHandler txtAltTableName.TextChanged, AddressOf txtTableTextChanged_TextChanged
        AddHandler txtAltTableName2.TextChanged, AddressOf txtTableTextChanged_TextChanged
        AddHandler txtSelectSQL.TextChanged, AddressOf txtTableTextChanged_TextChanged

        AddHandler chkTableFlag1.CheckedChanged, AddressOf chkFlag_CheckedChanged
        AddHandler chkTableFlag2.CheckedChanged, AddressOf chkFlag_CheckedChanged
        AddHandler chkTableFlag3.CheckedChanged, AddressOf chkFlag_CheckedChanged
        AddHandler chkTableFlag4.CheckedChanged, AddressOf chkFlag_CheckedChanged
        AddHandler chkTableFlag5.CheckedChanged, AddressOf chkFlag_CheckedChanged
        AddHandler chkTableFlag6.CheckedChanged, AddressOf chkFlag_CheckedChanged
        AddHandler chkTableFlag7.CheckedChanged, AddressOf chkFlag_CheckedChanged
        AddHandler chkTableFlag8.CheckedChanged, AddressOf chkFlag_CheckedChanged
        AddHandler chkTableFlag9.CheckedChanged, AddressOf chkFlag_CheckedChanged
        AddHandler chkTableFlag10.CheckedChanged, AddressOf chkFlag_CheckedChanged
        AddHandler chkIgnoreTable.CheckedChanged, AddressOf chkFlag_CheckedChanged


        AddHandler chkFlag1.CheckedChanged, AddressOf chkFieldFlag_CheckedChanged
        AddHandler chkFlag2.CheckedChanged, AddressOf chkFieldFlag_CheckedChanged
        AddHandler chkFlag3.CheckedChanged, AddressOf chkFieldFlag_CheckedChanged
        AddHandler chkFlag4.CheckedChanged, AddressOf chkFieldFlag_CheckedChanged
        AddHandler chkFlag5.CheckedChanged, AddressOf chkFieldFlag_CheckedChanged
        AddHandler chkFlag6.CheckedChanged, AddressOf chkFieldFlag_CheckedChanged
        AddHandler chkFlag7.CheckedChanged, AddressOf chkFieldFlag_CheckedChanged
        AddHandler chkFlag8.CheckedChanged, AddressOf chkFieldFlag_CheckedChanged
        AddHandler chkFlag9.CheckedChanged, AddressOf chkFieldFlag_CheckedChanged
        AddHandler chkFlag10.CheckedChanged, AddressOf chkFieldFlag_CheckedChanged
        AddHandler chkFlag11.CheckedChanged, AddressOf chkFieldFlag_CheckedChanged
        AddHandler chkFlag12.CheckedChanged, AddressOf chkFieldFlag_CheckedChanged
        AddHandler chkFlag13.CheckedChanged, AddressOf chkFieldFlag_CheckedChanged
        AddHandler chkFlag14.CheckedChanged, AddressOf chkFieldFlag_CheckedChanged
        AddHandler chkFlag15.CheckedChanged, AddressOf chkFieldFlag_CheckedChanged


        AddHandler chkIsAssociation.CheckedChanged, AddressOf chkFieldFlag_CheckedChanged
        AddHandler chkDirectFKSQLStatement.CheckedChanged, AddressOf chkFieldFlag_CheckedChanged
        AddHandler chkFKPopulateLoca.CheckedChanged, AddressOf chkFieldFlag_CheckedChanged

        AddHandler txtNameSpace.TextChanged, AddressOf txtGenerate_TextChanged
        AddHandler txtVersion.TextChanged, AddressOf txtGenerate_TextChanged
        AddHandler txtFileVersion.TextChanged, AddressOf txtGenerate_TextChanged
        AddHandler txtCompany.TextChanged, AddressOf txtGenerate_TextChanged
        AddHandler txtTrademark.TextChanged, AddressOf txtGenerate_TextChanged
        AddHandler txtConnectionString.TextChanged, AddressOf txtGenerate_TextChanged
        AddHandler txtAuthorName.TextChanged, AddressOf txtGenerate_TextChanged
        AddHandler txtClassName.TextChanged, AddressOf txtGenerate_TextChanged
        AddHandler txtDatabaseFile.TextChanged, AddressOf txtGenerate_TextChanged
        AddHandler txtOutputFile.TextChanged, AddressOf txtGenerate_TextChanged
        AddHandler txtOutputDirectory.TextChanged, AddressOf txtGenerate_TextChanged
        AddHandler txtTemplateFile.TextChanged, AddressOf txtGenerate_TextChanged
        AddHandler chkBuildSingleFile.CheckedChanged, AddressOf txtGenerate_TextChanged

        AddHandler txtMessage.TextChanged, AddressOf txtFieldTextChanged_TextChanged
        AddHandler txtForeignTableAlias.TextChanged, AddressOf txtFieldTextChanged_TextChanged
        AddHandler txtForeignFieldAlias.TextChanged, AddressOf txtFieldTextChanged_TextChanged
        AddHandler txtAltFieldName.TextChanged, AddressOf txtFieldTextChanged_TextChanged
        AddHandler txtFixedName.TextChanged, AddressOf txtFieldTextChanged_TextChanged
        AddHandler txtColDescription.TextChanged, AddressOf txtFieldTextChanged_TextChanged
        AddHandler txtColDescription.TextChanged, AddressOf txtFieldTextChanged_TextChanged
        AddHandler txtFormat.TextChanged, AddressOf txtFieldTextChanged_TextChanged
        AddHandler txtValidation1.TextChanged, AddressOf txtFieldTextChanged_TextChanged
        AddHandler txtValidation2.TextChanged, AddressOf txtFieldTextChanged_TextChanged
        AddHandler txtValidationMessage.TextChanged, AddressOf txtFieldTextChanged_TextChanged
        AddHandler txtFKDataSource.TextChanged, AddressOf txtFieldTextChanged_TextChanged
        AddHandler txtForeignSecondField.TextChanged, AddressOf txtFieldTextChanged_TextChanged
        AddHandler txtDefaultValue.TextChanged, AddressOf txtFieldTextChanged_TextChanged
        AddHandler txtCustom1.TextChanged, AddressOf txtFieldTextChanged_TextChanged
        AddHandler txtCustom2.TextChanged, AddressOf txtFieldTextChanged_TextChanged
        AddHandler txtCustom3.TextChanged, AddressOf txtFieldTextChanged_TextChanged
        AddHandler txtCustom4.TextChanged, AddressOf txtFieldTextChanged_TextChanged
        AddHandler txtSnippet1.TextChanged, AddressOf txtFieldTextChanged_TextChanged
        AddHandler txtSnippet2.TextChanged, AddressOf txtFieldTextChanged_TextChanged
        AddHandler txtWidth.TextChanged, AddressOf txtFieldTextChanged_TextChanged
        AddHandler txtOrdinal.TextChanged, AddressOf txtFieldTextChanged_TextChanged
        AddHandler txtNETDataType.TextChanged, AddressOf txtFieldTextChanged_TextChanged
        AddHandler txtIsNullable.TextChanged, AddressOf txtFieldTextChanged_TextChanged
        AddHandler txtDataType.TextChanged, AddressOf txtFieldTextChanged_TextChanged


        AddHandler chkMultiLine.CheckedChanged, AddressOf chkFieldFlag_CheckedChanged
        AddHandler chkMultiLine2.CheckedChanged, AddressOf chkFieldFlag_CheckedChanged
        AddHandler chkMultiLine3.CheckedChanged, AddressOf chkFieldFlag_CheckedChanged


        AddHandler txtCharWidth.TextChanged, AddressOf txtFieldTextChanged_TextChanged
        AddHandler txtCharWidth2.TextChanged, AddressOf txtFieldTextChanged_TextChanged
        AddHandler txtCharWidth3.TextChanged, AddressOf txtFieldTextChanged_TextChanged

        AddHandler txtXCoord.TextChanged, AddressOf txtFieldTextChanged_TextChanged
        AddHandler txtYCoord.TextChanged, AddressOf txtFieldTextChanged_TextChanged
        AddHandler txtXCoord2.TextChanged, AddressOf txtFieldTextChanged_TextChanged
        AddHandler txtYCoord2.TextChanged, AddressOf txtFieldTextChanged_TextChanged
        AddHandler txtXCoord3.TextChanged, AddressOf txtFieldTextChanged_TextChanged
        AddHandler txtYCoord3.TextChanged, AddressOf txtFieldTextChanged_TextChanged

        AddHandler txtPixelWidth.TextChanged, AddressOf txtFieldTextChanged_TextChanged
        AddHandler txtPixelWidth2.TextChanged, AddressOf txtFieldTextChanged_TextChanged
        AddHandler txtPixelWidth3.TextChanged, AddressOf txtFieldTextChanged_TextChanged

        AddHandler txtCharRows.TextChanged, AddressOf txtFieldTextChanged_TextChanged
        AddHandler txtCharRows2.TextChanged, AddressOf txtFieldTextChanged_TextChanged
        AddHandler txtCharRows3.TextChanged, AddressOf txtFieldTextChanged_TextChanged

        AddHandler txtPixelHeight.TextChanged, AddressOf txtFieldTextChanged_TextChanged
        AddHandler txtPixelHeight2.TextChanged, AddressOf txtFieldTextChanged_TextChanged
        AddHandler txtPixelHeight3.TextChanged, AddressOf txtFieldTextChanged_TextChanged

        AddHandler txtFormat2.TextChanged, AddressOf txtFieldTextChanged_TextChanged
        AddHandler txtFKSelectMethod.TextChanged, AddressOf txtFieldTextChanged_TextChanged
        AddHandler txtForeignFieldDataType.TextChanged, AddressOf txtFieldTextChanged_TextChanged
        AddHandler txtForeignTableAlias.TextChanged, AddressOf txtFieldTextChanged_TextChanged

        Dim retObject As Object

        dgvFieldFunctions.AutoGenerateColumns = False
        AddColumn("PropertyID", dgvFieldFunctions, New DataGridViewTextBoxColumn, Nothing, 120, "Property")
        AddColumn("Value", dgvFieldFunctions, New DataGridViewTextBoxColumn, Nothing, 550, "Value")
        AddColumn("Type", dgvFieldFunctions, New DataGridViewComboBoxColumn, New String() {"Table", "Field"}, 60, "Type")
        AddColumn("Custom", dgvFieldFunctions, New DataGridViewComboBoxColumn, New String() {"New only", "All fields", "Existing"}, 100, "Update")

        If My.Computer.FileSystem.FileExists(My.Application.Info.DirectoryPath & "\default.dbs") Then
            retObject = Utils.LoadSerializedFile(My.Application.Info.DirectoryPath & "\default.dbs")
            layoutConfig = retObject
            LoadConfigSettingsFlags()
            titleBar(3) = retObject.FileName
        End If

        pageObjects(3) = layoutConfig

        LoadFlagsWithConfigSettings()

        ' CompProperty CompOperator CompValue 
        dgvConditions.AutoGenerateColumns = False

        'field conditions
        AddColumn("CompProperty", dgvConditions, New DataGridViewComboBoxColumn, New String() {"(None)", "AltTableName", "NETDataType", "FixedName", "ProperNETDataType", "DATA_TYPE", "BaseDataType", "ISIDENTITY", "IS_NULLABLE", "Width", "TableName", "ClassName", "NameSpace", _
"DatabaseFile", "DatabaseName", "OutputFile", "AuthorName", "Modified", "NameSpace", "Assembly", "ShortDateTime", "LongDateTime", "FieldWidth", "IsVirtualField", _
"Flag1", "Flag2", "Flag3", "Flag4", "Flag5", "Flag6", "Flag7", "Flag8", "Flag9", "Flag10", "Flag11", "Flag12", "Flag13", "Flag14", "Flag15", "CharWidth", "CharRows", "CharWidth2", "CharRows2", "PixelWidth", "PixelHeight", _
"PixelWidth2", "PixelHeight2", "Format", "Format2"}, 200, "Property")
        AddColumn("CompOperator", dgvConditions, New DataGridViewComboBoxColumn, New String() {"Equals (=)", "Property Exists", "Is Not Empty/blank", "Greater Than (>)", "Less Than (<)"}, 150, "Operator")
        AddColumn("CompValue", dgvConditions, New DataGridViewTextBoxColumn, Nothing, 500, "Value")

        dgvSecConditions.AutoGenerateColumns = False

        'table/section conditions
        AddColumn("CompProperty", dgvSecConditions, New DataGridViewComboBoxColumn, New String() {"(None)", "AltTableName", "NETDataType", "FieldWidth", _
"TableFlag1", "TableFlag2", "TableFlag3", "TableFlag4", "TableFlag5", "TableFlag6", "TableFlag7", "TableFlag8", "TableFlag9", "TableFlag10"}, 150, "Property")
        AddColumn("CompOperator", dgvSecConditions, New DataGridViewComboBoxColumn, New String() {"Equals (=)", "Property Exists", "Is Not Empty/blank", "Greater Than (>)", "Less Than (<)"}, 150, "Operator")
        AddColumn("CompValue", dgvSecConditions, New DataGridViewTextBoxColumn, Nothing, 500, "Value")

    End Sub



    Sub LoadConfigSettingsFlags()
        Dim tBox As New Control, TTIP As New ToolTip()

        'loop through all field layout controls and populate form values and tool tips with corresponding value stored 
        'in dictionary using the control's Tag property
        For Each tBox In tabFieldSettings.Controls
            If Not tBox.Tag Is Nothing AndAlso tBox.Tag.GetType.ToString = "System.String" And TypeOf tBox Is TextBox Then

                If tBox.Name.Substring(0, 12) = "txtFlagLabel" Then
                    tBox.Text = layoutConfig.PairValues(tBox.Tag.ToString)(0)
                ElseIf tBox.Name.ToString.Substring(0, 12) = "txtFlagDescr" Then
                    tBox.Text = layoutConfig.PairValues(tBox.Tag.ToString)(1)
                End If
            End If
        Next

        For Each tBox In tabTableSettings.Controls
            If Not tBox.Tag Is Nothing AndAlso tBox.Tag.GetType.ToString = "System.String" And TypeOf tBox Is TextBox Then
                If Not tBox.Name.Substring(0, 8) = "txtTable" Then
                    'tBox.Text = layoutConfig.PairValues(tBox.Tag.ToString)(0)
                ElseIf tBox.Name.Substring(0, 17) = "txtTableFlagLabel" Then
                    tBox.Text = layoutConfig.PairValues(tBox.Tag.ToString)(0)
                ElseIf tBox.Name.ToString.Substring(0, 17) = "txtTableFlagDescr" Then
                    tBox.Text = layoutConfig.PairValues(tBox.Tag.ToString)(1)
                End If
            End If
        Next

        txtFunctionCode.Text = layoutConfig.PairValues("FunctionCode")(1)
        dgvFieldFunctions.DataSource = layoutConfig.FieldFunctions


        Dim confValues As PairValue, setControl As Control
        If Not layoutConfig.PropertyCustomizations Is Nothing Then

            For Each confValues In layoutConfig.PropertyCustomizations
                setControl = propertyDict(confValues.PropertyID)
                setControl.Parent.Controls("lbl" & propertyDict(confValues.PropertyID).Name.Substring(3)).Text = confValues.Type
                propertyDict(confValues.PropertyID).Tag = confValues.Value
            Next
        Else
            layoutConfig.PropertyCustomizations = New BindingList(Of PairValue)
        End If

        dgvPropCustom.DataSource = layoutConfig.PropertyCustomizations


    End Sub

    Sub LoadFlagsWithConfigSettings()
        Dim tBox As New Control, TTIP As New ToolTip()

        'loop through all field layout controls and populate form values and tool tips with corresponding value stored 
        'in dictionary using the control's Tag property
        For Each tBox In tabColumnInfo.Controls
            If Not tBox.Tag Is Nothing AndAlso tBox.Tag.GetType.ToString = "System.String" And TypeOf tBox Is CheckBox Then
                If tBox.Tag.ToString.Substring(0, 4) = "Flag" Then
                    tBox.Text = layoutConfig.PairValues(tBox.Tag.ToString)(0)
                    TTIP.SetToolTip(tBox, tBox.Tag & " " & layoutConfig.PairValues(tBox.Tag.ToString)(1))
                End If
            End If
        Next

        For Each tBox In pnlTableInfo.Controls
            If Not tBox.Tag Is Nothing AndAlso tBox.Tag.GetType.ToString = "System.String" And TypeOf tBox Is CheckBox Then
                If tBox.Tag.ToString.Substring(0, 9) = "TableFlag" Then
                    tBox.Text = layoutConfig.PairValues(tBox.Tag.ToString)(0)
                    TTIP.SetToolTip(tBox, tBox.Tag & " " & layoutConfig.PairValues(tBox.Tag.ToString)(1))
                End If
            End If
        Next

        txtFunctionCode.Text = layoutConfig.PairValues("FunctionCode")(1)
    End Sub


    Sub PopulateToolTips(ByVal controlPanel As Control, ByVal addControls As Boolean)
        Dim tBox As New Control
        Dim TTIP As New ToolTip()
        Dim propList As DataGridViewComboBoxColumn

        propList = dgvPropCustom.Columns(0)

        'loop through all controls and populate form values with corresponding value stored 
        'in dictionary using the control's Tag property
        If addControls Then

            For Each tBox In controlPanel.Controls
                If Not tBox.Tag Is Nothing AndAlso tBox.Tag.GetType.ToString = "System.String" And tBox.Tag <> "" Then
                    TTIP.SetToolTip(tBox, tBox.Tag)

                    'populate dropdown and corresponding list of controls
                    If Not tBox.Name.StartsWith("chkFlag") Then
                        propList.Items.Add(tBox.Tag)
                        propertyDict.Add(tBox.Tag, tBox)
                    End If

                End If
            Next

        End If
    End Sub


    Sub AddColumn(ByVal name As String, ByVal datagridview As DataGridView, ByVal control As Object, ByVal values() As String, ByVal Width As Integer, ByVal headerText As String)

        Dim cboColumn As DataGridViewComboBoxColumn

        cboColumn = New DataGridViewComboBoxColumn

        control.Width = Width
        control.HeaderText = headerText

        If TypeOf control Is DataGridViewComboBoxColumn Then

            With control
                .DataPropertyName = name
                For Each item As String In values
                    .Items.Add(item)
                Next
                .Name = name


            End With
        ElseIf TypeOf control Is DataGridViewTextBoxColumn Then
            With control
                .Name = name
                .DataPropertyName = name
            End With

        End If

        datagridview.Columns.Add(control)
    End Sub

    ''' <summary>
    ''' Updates appropriate template panel depending upon what node level is selected
    ''' </summary>
    ''' <param name="sender"></param>
    ''' <param name="e"></param>
    ''' <remarks></remarks>
    Private Sub TreeView1_AfterSelect(ByVal sender As System.Object, ByVal e As System.Windows.Forms.TreeViewEventArgs) Handles TreeView1.AfterSelect
        Dim streenode As TreeNode = TreeView1.SelectedNode, section As New SectionTemplate   'SectionsPanel


        Dim dirtyFlag As Boolean

        dirtyFlag = idDirty(selectedPage)

        selectedLevel = streenode.Level
        'is template section selected
        If streenode.Name.Substring(0, 4) = "sec_" Then
            section = streenode.Tag

            Me.SectionsPanel.Visible = True
            Me.txtDescription.Text = section.Description
            Me.txtPostSection.Text = section.PostFixTemplate
            Me.txtPreSection.Text = section.PrefixTemplate
            txtSectionDetail.Text = section.Detail
            pnlRoot.Visible = False
            pnlDetail.Visible = False

            'add condition if not there... delete this
            If streenode.Tag.Conditions Is Nothing Then
                Dim a As New Condition
                conditionArray = New BindingList(Of Condition)
                If cboFieldType.Text <> "" Then
                    conditionArray.Add(a)
                End If
                streenode.Tag.Conditions = conditionArray
            End If

            dgvSecConditions.DataSource = streenode.Tag.Conditions

        ElseIf streenode.Name.Substring(0, 4) = "det_" Then
            pnlDetail.Visible = True
            txtDetailTemplate.Text = CType(streenode.Tag.Template, String)
            txtDetailType.Text = streenode.Tag.Description
            cboDataTypes.Text = streenode.Tag.Type
            cboFieldType.Text = streenode.Tag.FieldType
            cboLevel.Text = streenode.Tag.Level
            cboNextStep.SelectedIndex = streenode.Tag.NextStep
            chkIsEmpty.Checked = streenode.Tag.EmptyField
            txtDetailTemplate.Visible = Not chkIsEmpty.Checked
            chkOr.Checked = streenode.Tag.OrField
            lblTemplate.Visible = Not chkIsEmpty.Checked
            pnlRoot.Visible = False
            SectionsPanel.Visible = False

            If streenode.Tag.Conditions Is Nothing Then
                Dim a As New Condition
                conditionArray = New BindingList(Of Condition) 'ArrayList

                If cboFieldType.Text <> "" Then
                    conditionArray.Add(a)
                End If
                streenode.Tag.Conditions = conditionArray
            End If

            dgvConditions.DataSource = streenode.Tag.Conditions

        ElseIf streenode.Name.Substring(0, 4) = "root" Then
            SectionsPanel.Visible = False
            pnlDetail.Visible = False
            pnlRoot.Visible = True
   
            txtRootDescription.Text = streenode.Tag.LayoutName
            txtRootPostTemplate.Text = streenode.Tag.PostFixTemplate
            txtRootPreTemplate.Text = streenode.Tag.PreFixTemplate
        End If

        If btnSaveFile.Enabled And Not dirtyFlag Then
            btnSaveFile.Enabled = False
            idDirty(selectedPage) = False
        End If

        RefreshAddDeleteButtons()

    End Sub
    ''' <summary>
    ''' Populate generate values with corresponding value stored in dictionary using the control's Tag property
    ''' </summary>
    ''' <remarks></remarks>
    Sub PopulateGenericFields()
        Dim tBox As New Control

        'procees each control on generate properties tab 
        For Each tBox In TabPage3.Controls


            If Not tBox.Tag Is Nothing AndAlso tBox.Tag.GetType.ToString = "System.String" And TypeOf tBox Is CheckBox Then
                Dim checkBox As CheckBox
                checkBox = CType(tBox, CheckBox)

                Try
                    checkBox.Checked = tgenerateParameters.Values(tBox.Tag)

                Catch e As Exception

                End Try

            ElseIf Not tBox.Tag Is Nothing AndAlso tBox.Tag.GetType.ToString = "System.String" Then
                Try
                    tBox.Text = tgenerateParameters.Values(tBox.Tag)
                Catch e As Exception

                End Try
            End If
        Next

    End Sub

    Sub UpdateGenericFieldsWithFormValues()
        Dim tBox As New Control

        'loop through all controls and populate form values with corresponding value stored 
        'in dictionary using the control's Tag property
        For Each tBox In TabPage3.Controls

            If Not tBox.Tag Is Nothing AndAlso tBox.Tag.GetType.ToString = "System.String" Then
                tgenerateParameters.Values(tBox.Tag) = tBox.Text
            End If

            If Not tBox.Tag Is Nothing AndAlso tBox.Tag.GetType.ToString = "System.String" And TypeOf tBox Is CheckBox Then
                Dim checkBox As CheckBox
                checkBox = CType(tBox, CheckBox)
                tgenerateParameters.Values(tBox.Tag) = checkBox.Checked

            End If


        Next

    End Sub
    Private Sub DeletecmdAddDataType_Click(ByVal sender As System.Object, ByVal e As System.EventArgs)

        Dim seltreenode As TreeNode = TreeView1.SelectedNode, newNode As New TreeNode
        Dim sectionTemplate As New SectionTemplate
        Dim detaillayout As New DataType

        sectionTemplate = seltreenode.Tag
        detaillayout.Description = "New type"
        newNode.Tag = detaillayout
        newNode.Text = "New Datatype"
        newNode.Name = "det_New datatype"
        seltreenode.Nodes.Add(newNode)
    End Sub

    Private Sub txtPreSection_Enter(ByVal sender As Object, ByVal e As System.EventArgs) Handles txtPreSection.Enter
        selectedControl = txtPreSection
        listProperties.Visible = True
        Me.Select()

    End Sub

    Private Sub txtPreSection_Leave(ByVal sender As Object, ByVal e As System.EventArgs) Handles txtPreSection.Leave
        listProperties.Visible = False
        selectedControl = Nothing
    End Sub


    Private Sub txtPreSection_TextChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles txtPreSection.TextChanged
        TreeView1.SelectedNode.Tag.PrefixTemplate = Me.txtPreSection.Text
        FlagDirty()
    End Sub

    Private Sub txtSectionDetail_Enter(ByVal sender As Object, ByVal e As System.EventArgs) Handles txtSectionDetail.Enter
        selectedControl = txtSectionDetail
        listProperties.Visible = True
        Me.Select()

    End Sub

    Private Sub txtSectionDetail_Leave(ByVal sender As Object, ByVal e As System.EventArgs) Handles txtSectionDetail.Leave
        selectedControl = Nothing
        listProperties.Visible = False
    End Sub

    Private Sub txtSectionDetail_TextChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles txtSectionDetail.TextChanged
        TreeView1.SelectedNode.Tag.Detail = txtSectionDetail.Text
        FlagDirty()
    End Sub

    Private Sub txtPostSection_Enter(ByVal sender As Object, ByVal e As System.EventArgs) Handles txtPostSection.Enter
        selectedControl = txtPostSection
        listProperties.Visible = True
        Me.Select()

    End Sub

    Private Sub txtPostSection_Leave(ByVal sender As Object, ByVal e As System.EventArgs) Handles txtPostSection.Leave
        selectedControl = Nothing
        listProperties.Visible = False

    End Sub

    Private Sub txtPostSection_TextChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles txtPostSection.TextChanged
        TreeView1.SelectedNode.Tag.PostFixTemplate = Me.txtPostSection.Text
        FlagDirty()
    End Sub

    Private Sub txtDescription_TextChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles txtDescription.TextChanged
        TreeView1.SelectedNode.Tag.Description = txtDescription.Text
        TreeView1.SelectedNode.Text = txtDescription.Text
        FlagDirty()
    End Sub





    ''' <summary>
    ''' Displays appropriate panel and corresponding data depending on what node is selected in database treeviee
    ''' </summary>
    ''' <param name="sender"></param>
    ''' <param name="e"></param>
    ''' <remarks></remarks>
    Private Sub tvwDatabaseLO_AfterSelect(ByVal sender As System.Object, ByVal e As System.Windows.Forms.TreeViewEventArgs) Handles tvwDatabaseLO.AfterSelect
        Dim streenode As TreeNode = tvwDatabaseLO.SelectedNode, section As New SectionTemplate
        Dim dirtyFlag As Boolean
        dirtyFlag = idDirty(selectedPage)

        'database node
        If streenode.Name.Substring(0, 3) = "db_" Then
            txtDatabaseName.Text = streenode.Tag.Name
            btnGeneratePopulate.Visible = True

            txtDataSourceName.Text = streenode.Tag.DataSourceName
            txtDBConnectionString.Text = streenode.Tag.ConnectionString

            pnlServerInfo.Visible = False
            pnlTableInfo.Visible = False
            pnlDatabaseInfo.Visible = True
            pnlColumnInfo.Visible = False
        ElseIf streenode.Name.Substring(0, 3) = "tl_" Then  'table node
            btnGeneratePopulate.Visible = False
            txtTableName.Text = streenode.Tag.Name
            txtTableDescription.Text = streenode.Tag.Description

            pnlTableInfo.Visible = True
            pnlDatabaseInfo.Visible = False
            pnlColumnInfo.Visible = False
            pnlServerInfo.Visible = False

            PopulateColumnFieldsTab(streenode.Tag.Properties, pnlTableInfo)


        ElseIf streenode.Name.Substring(0, 4) = "col_" Then 'column node
            btnGeneratePopulate.Visible = False
            txtFieldName.Text = streenode.Tag.Name
            txtGenericType.Text = streenode.Tag.BaseDataType
            txtBaseDataType.Text = streenode.Tag.GenericType

            chkIgnore.Checked = streenode.Tag.Ignore
            chkKey.Checked = streenode.Tag.Iskey
            chkColForeignKey.Checked = streenode.Tag.IsForeignKey
            chkIsVirtualField.Checked = streenode.Tag.IsVirtualField
            pnlServerInfo.Visible = False
            pnlTableInfo.Visible = False
            pnlDatabaseInfo.Visible = False
            pnlColumnInfo.Visible = True

            columnDictionary = streenode.Tag.Values
            valsgrid.Rows.Clear()

            cboAssociationType.Visible = streenode.Tag.IsVirtualField
            chkIsAssociation.Visible = streenode.Tag.IsVirtualField
            lblAssociation.Visible = streenode.Tag.IsVirtualField
            txtFieldName.ReadOnly = Not streenode.Tag.IsVirtualField
            txtNETDataType.ReadOnly = Not streenode.Tag.IsVirtualField
            txtWidth.ReadOnly = Not streenode.Tag.IsVirtualField
            txtDataType.ReadOnly = Not streenode.Tag.IsVirtualField
            txtGenericType.ReadOnly = Not streenode.Tag.IsVirtualField
            txtIsNullable.ReadOnly = Not streenode.Tag.IsVirtualField
            Dim countValues As Integer = 0

            For Each pv As KeyValuePair(Of String, PropertyValue) In columnDictionary
                Dim aval(1) As String

                If Not pv.Value.System Then
                    aval(0) = pv.Key
                    aval(1) = pv.Value.Value
                    valsgrid.Rows.Add(aval)
                End If
            Next

            PopulateColumnFieldsTab(columnDictionary, tabColumnInfo) '
            PopulateColumnFieldsTab(columnDictionary, tabColumnInfo2)

        ElseIf streenode.Name.Substring(0, 4) = "root" Then 'root server node
            cboDatabaseType.Text = streenode.Tag.DatabaseType
            txtServerName.Text = streenode.Tag.Name
            txtServerUserID.Text = streenode.Tag.UserName
            txtServerPassword.Text = streenode.Tag.Password
            txtServerPort.Text = streenode.Tag.Port
            chkUseNTAuthentication.Checked = streenode.Tag.UseNTAuthentication
            pnlServerInfo.Visible = True
            pnlTableInfo.Visible = False
            pnlDatabaseInfo.Visible = False
            pnlColumnInfo.Visible = False
            pnlDetail.Visible = False
            btnGeneratePopulate.Visible = True

        End If

        If btnSaveFile.Enabled And Not dirtyFlag Then
            btnSaveFile.Enabled = False
            idDirty(selectedPage) = False
        End If

        RefreshAddDeleteButtons()
    End Sub



    Private Sub chkKey_CheckedChanged(ByVal sender As System.Object, ByVal e As System.EventArgs)
        tvwDatabaseLO.SelectedNode.Tag.IsKey = chkKey.Checked
    End Sub

    Private Sub tabLayout_KeyDown(ByVal sender As Object, ByVal e As System.Windows.Forms.KeyEventArgs) Handles tabLayout.KeyDown
        Dim ctl As Control = Nothing

        Exit Sub

        ctl = Me.ActiveControl
        Debug.WriteLine(e.KeyCode)

        If (Not (e.KeyCode < 42 And Not e.Shift)) And e.KeyData < 255 Then


            'if active control is text box then flag page as 'dirty' and enable save button
            If TypeOf ctl Is TextBox Then
                'make sure control is not readonly
                If Not CType(ctl, TextBox).ReadOnly Then
                    FlagDirty()
                End If
            ElseIf TypeOf ctl Is ComboBox Then
                FlagDirty()
            ElseIf TypeOf ctl Is CheckBox Then
                If Not CType(ctl, CheckBox).Enabled Then
                    FlagDirty()
                End If
            End If
        Else
            ctl = Nothing

        End If

    End Sub
    ''' <summary>
    ''' 
    ''' </summary>
    ''' <param name="sender"></param>
    ''' <param name="e"></param>
    ''' <remarks></remarks>
    Private Sub tabLayout_KeyPress(ByVal sender As Object, ByVal e As System.Windows.Forms.KeyPressEventArgs) Handles tabLayout.KeyPress

    End Sub

    Sub FlagDirty()
        idDirty(selectedPage) = True
        If Not btnSaveFile.Enabled Then
            btnSaveFile.Enabled = True

        End If

    End Sub


    Private Sub tabLayout_SelectedIndexChanged(ByVal sender As Object, ByVal e As System.EventArgs) Handles tabLayout.SelectedIndexChanged
        selectedPage = sender.selectedtab.TabIndex '.ToString)

        btnLoadFile.Text = "Load " & fileTypes(selectedPage * 3)
        btnSaveFile.Text = "Save " & fileTypes(selectedPage * 3)
        btnNewFile.Text = "New " & fileTypes(selectedPage * 3)

        btnSaveFile.Enabled = idDirty(selectedPage)


        Me.Text = My.Application.Info.Title & " " & titleBar(selectedPage)

        RefreshAddDeleteButtons()
    End Sub

    Sub RefreshAddDeleteButtons()


        If selectedPage = 1 Then
            Dim dbSelected As Integer = 0

            If Not tvwDatabaseLO.SelectedNode Is Nothing Then
                dbSelected = tvwDatabaseLO.SelectedNode.Level
            End If

            btnAddNewItem.Visible = IIf(tvwDatabaseLO.Nodes.Count > 0 And Not tvwDatabaseLO.SelectedNode Is Nothing And dbSelected = 2, True, False)
            btnDeleteItem.Visible = IIf(tvwDatabaseLO.Nodes.Count > 0 And Not tvwDatabaseLO.SelectedNode Is Nothing And dbSelected = 3 AndAlso tvwDatabaseLO.SelectedNode.Tag.IsVirtualField, True, False)

            btnAddNewItem.Text = "Add Virtual Field"
            btnDeleteItem.Text = "Delete Virtual Field"

        End If

        'if second or third page enable additional buttons
        If selectedPage > 0 And selectedPage < 3 Then

            If selectedPage = 1 Then
                btnGeneratePopulate.Visible = IIf(Me.tvwDatabaseLO.Nodes.Count > 0, True, False)
                btnGeneratePopulate.Text = "Populate Database"

            Else
                btnAddNewItem.Visible = False
                btnDeleteItem.Visible = False

                btnGeneratePopulate.Visible = True
                btnGeneratePopulate.Text = "Generate Output"
            End If

        Else 'refresh first tab buttons
            btnGeneratePopulate.Visible = False

            btnAddNewItem.Visible = IIf(selectedLevel < 2 And TreeView1.Nodes.Count > 0 And Not TreeView1.SelectedNode Is Nothing, True, False)
            btnDeleteItem.Visible = IIf(selectedLevel > 0 And TreeView1.Nodes.Count > 0 And Not TreeView1.SelectedNode Is Nothing, True, False)

            btnAddNewItem.Text = "Add " & IIf(selectedLevel = 0, "Section", "Detail")
            btnDeleteItem.Text = "Delete " & IIf(selectedLevel = 1, "Section", "Detail")
        End If

    End Sub

    Private Sub tabLayout_TabIndexChanged(ByVal sender As Object, ByVal e As System.EventArgs) Handles tabLayout.TabIndexChanged
        selectedPage = sender.selectedtab.TabIndex
    End Sub


    Private Sub txtServerUserID_TextChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles txtServerUserID.TextChanged
        tvwDatabaseLO.SelectedNode.Tag.UserName = txtServerUserID.Text
        FlagDirty()
    End Sub

    Private Sub txtServerPassword_TextChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles txtServerPassword.TextChanged
        tvwDatabaseLO.SelectedNode.Tag.Password = txtServerPassword.Text
        FlagDirty()
    End Sub

    Private Sub chkUseNTAuthentication_CheckedChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles chkUseNTAuthentication.CheckedChanged
        tvwDatabaseLO.SelectedNode.Tag.UseNTAuthentication = CBool(chkUseNTAuthentication.Checked)
        txtServerPassword.Enabled = Not chkUseNTAuthentication.Checked
        txtServerUserID.Enabled = Not chkUseNTAuthentication.Checked
        FlagDirty()
    End Sub

    Private Sub txtServerName_TextChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles txtServerName.TextChanged
        tvwDatabaseLO.SelectedNode.Tag.Name = txtServerName.Text
        FlagDirty()
    End Sub


    Private Sub cmdBrowseTemplateFile_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles cmdBrowseTemplateFile.Click
        SelectFile(fileTypes(0) & "|" & fileTypes(1), txtTemplateFile)
    End Sub

    Sub SelectFile(ByVal filterText As String, ByVal textCtl As TextBox)
        dlgOpenFile.Filter = filterText
        dlgOpenFile.FileName = ""
        dlgOpenFile.CheckFileExists = False
        If dlgOpenFile.ShowDialog() = Windows.Forms.DialogResult.OK Then
            textCtl.Text = dlgOpenFile.FileName
            FlagDirty()
        End If

    End Sub

    Sub SelectFolder(ByVal textCtl As TextBox)

        If dlgBrowseFolder.ShowDialog() = Windows.Forms.DialogResult.OK Then
            textCtl.Text = dlgBrowseFolder.SelectedPath

            'append \ if not there
            If Not textCtl.Text.EndsWith("\") Then
                textCtl.Text = textCtl.Text & "\"
            End If

        End If

    End Sub

    Private Sub cmdBrowseOutputFile_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles cmdBrowseOutputFile.Click
        SelectFile("All Files|*.*", txtOutputFile)
        txtOutputFile.Text = System.IO.Path.GetFileName(txtOutputFile.Text)
    End Sub

    Private Sub cmdBrowseDatabaseFile_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles cmdBrowseDatabaseFile.Click
        SelectFile(fileTypes(3) & "|" & fileTypes(4), txtDatabaseFile)

        If Not txtDatabaseFile.Text = "" Then
            dbServer = Utils.LoadSerializedFile(txtDatabaseFile.Text) ', "dban." & fileTypes(5))

            If Not dbServer.Databases Is Nothing Then PopulateDatabaseList()
        End If

    End Sub

    Sub PopulateDatabaseList()
        Dim databaseList As New ArrayList

        For Each kvp As KeyValuePair(Of String, DatabaseStructure) In dbServer.Databases
            databaseList.Add(kvp.Key)
        Next

        cboDBs.DataSource = databaseList
    End Sub


    Sub PopulateTableList()
        Dim tableList As New ArrayList

        If dbServer Is Nothing Or Not dbServer.Databases.ContainsKey(cboDBs.Text) Then
            tableList.Clear()
            Exit Sub
        End If

        'dbServer.Databases.ContainsKey (cboDBs.Text).TableLayouts.Count
        For Each kvp As KeyValuePair(Of String, TableLayout) In dbServer.Databases(cboDBs.Text).TableLayouts
            tableList.Add(kvp.Key)
        Next

        cboTables.DataSource = tableList
    End Sub

    Private Sub cmdBrowseOutputDirectory_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles cmdBrowseOutputDirectory.Click
        SelectFolder(txtOutputDirectory)
    End Sub


    Private Sub cboDBs_SelectionChangeCommitted(ByVal sender As Object, ByVal e As System.EventArgs) Handles cboDBs.SelectionChangeCommitted
        cboDBs.Text = cboDBs.SelectedItem
        tgenerateParameters.Values("DatabaseName") = cboDBs.SelectedItem

        PopulateTableList()
        cboTables.Text = tgenerateParameters.Values("TableName")

        If Not btnSaveFile.Enabled Then btnSaveFile.Enabled = True
    End Sub


    Private Sub btnGeneratePopulate_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnGeneratePopulate.Click
        Dim streenode As TreeNode = tvwDatabaseLO.SelectedNode
        Dim databaseList As Generic.List(Of String) = Nothing

        Windows.Forms.Cursor.Current = System.Windows.Forms.Cursors.WaitCursor

        Select Case selectedPage

            Case 1
                Dim PopulateForm As New PopulateOptions, process As Boolean
                selectedLevel = streenode.Level

                'if level is root then populate whole server
                If selectedLevel = 0 Then

                    Try
                        databaseList = GetDatabaseList(tvwDatabaseLO.Nodes(0).Tag)

                    Catch ex As Exception
                        Windows.Forms.Cursor.Current = System.Windows.Forms.Cursors.Default
                        ShowError("Error connecting to server. Terminating processing " & ex.Message, ex.StackTrace)

                        Exit Sub

                    End Try

                    'populate database checkbox list
                    For Each database As String In databaseList
                        PopulateForm.lstTableList.Items.Add(database, True)
                    Next

                Else 'otherwise just do selected database
                    PopulateForm.lstTableList.Visible = False
                    PopulateForm.lstTableList.Enabled = False
                End If

                process = PopulateForm.ShowDialog = Windows.Forms.DialogResult.OK

                If process Then
                    addEntities = PopulateForm.chkBuildEntityFields.Checked

                    For Each rb As RadioButton In PopulateForm.grpExecuteFieldScripts.Controls
                        If rb.Checked Then
                            processFieldScripts = rb.TabIndex
                            Exit For
                        End If

                    Next

                    For Each rb As RadioButton In PopulateForm.grpExecuteTablesScripts.Controls
                        If rb.Checked Then
                            processTableScripts = rb.TabIndex
                            Exit For
                        End If

                    Next


                    'populate all databases or just selected database?
                    If selectedLevel = 0 Then
                        databaseList.Clear()

                        Dim n As Integer

                        For n = 0 To PopulateForm.lstTableList.Items.Count - 1
                            If PopulateForm.lstTableList.GetItemChecked(n) Then
                                databaseList.Add(PopulateForm.lstTableList.Items(n))
                            End If
                        Next

                        PopulateServerObjects(tvwDatabaseLO.Nodes(0).Tag, databaseList)

                    Else 'otherwise just do selected database
                        Windows.Forms.Cursor.Current = System.Windows.Forms.Cursors.WaitCursor

                        PopulateDatabaseObject(txtDatabaseName.Text, tvwDatabaseLO.Nodes(0).Tag)
                    End If
                    FlagDirty()
                End If

            Case 2 'generate output for selected template
                GenerateOutput()


        End Select

        Windows.Forms.Cursor.Current = System.Windows.Forms.Cursors.Default

    End Sub


    Sub GenerateOutput()
        Dim codeGeneration As New GenerateCode

        UpdateGenericFieldsWithFormValues()
        codeGeneration.ScriptLogic = layoutConfig.PairValues("FunctionCode")(1)

        Try

            codeGeneration.GenerateParameters = tgenerateParameters
            codeGeneration.LoadDatabaseStructure()
            codeGeneration.LoadTemplate()
            codeGeneration.GenerateOutput()
        Catch cgex As CodeGenException

            ShowError(cgex.Message, cgex.ToString)

        Catch ex As Exception
            'ShowError("Error evaluating function when assigning value to table property :" & pva.PropertyID & vbCrLf & BuildError(ex), ex.ToString)                    
            ShowError(ex.Message, ex.ToString)

        End Try


    End Sub


    Private Sub chkColForeignKey_CheckedChanged(ByVal sender As System.Object, ByVal e As System.EventArgs)
        Dim seltreenode As TreeNode = tvwDatabaseLO.SelectedNode
        seltreenode.Tag.IsForeignKey = chkColForeignKey.Checked
    End Sub


    Sub PopulateColumnFields(ByVal dict As Dictionary(Of String, String), ByVal controlPanel As Panel)
        Dim tBox As New Control

        'loop through all controls and populate form values with corresponding value stored 
        'in dictionary using the control's Tag property
        For Each tBox In controlPanel.Controls
            If Not tBox.Tag Is Nothing AndAlso tBox.Tag.GetType.ToString = "System.String" And tBox.Tag <> "" Then

                Try
                    If TypeOf tBox Is TextBox Then
                        tBox.Text = dict(tBox.Tag)
                    ElseIf TypeOf tBox Is CheckBox Then
                        Dim checkBox As CheckBox
                        checkBox = CType(tBox, CheckBox)
                        checkBox.Checked = dict(tBox.Tag)
                    Else
                        tBox.Text = dict(tBox.Tag)
                    End If

                Catch e As KeyNotFoundException
                    If TypeOf tBox Is CheckBox Then
                        dict.Add(tBox.Tag, "False")
                    Else
                        dict.Add(tBox.Tag, "")
                        tBox.Text = ""
                    End If

                End Try
            End If
        Next

    End Sub
    Sub PopulateColumnFieldsTabs(ByVal dict As Dictionary(Of String, String), ByVal controlPanel As Control)
        Dim tBox As New Control

        'loop through all controls and populate form values with corresponding value stored 
        'in dictionary using the control's Tag property
        For Each tBox In controlPanel.Controls
            If Not tBox.Tag Is Nothing AndAlso tBox.Tag.GetType.ToString = "System.String" And tBox.Tag <> "" Then

                Try
                    If TypeOf tBox Is TextBox Then
                        tBox.Text = dict(tBox.Tag)
                    ElseIf TypeOf tBox Is CheckBox Then
                        Dim checkBox As CheckBox
                        checkBox = CType(tBox, CheckBox)
                        checkBox.Checked = dict(tBox.Tag)
                    Else
                        tBox.Text = dict(tBox.Tag)
                    End If

                Catch e As KeyNotFoundException
                    If TypeOf tBox Is CheckBox Then
                        dict.Add(tBox.Tag, "False")
                    Else
                        dict.Add(tBox.Tag, "")
                        tBox.Text = ""
                    End If

                End Try
            End If
        Next

    End Sub

    Sub PopulateColumnFieldsTab(ByVal dict As Dictionary(Of String, PropertyValue), ByVal controlPanel As Control)
        Dim tBox As New Control

        'loop through all controls and populate form values with corresponding value stored 
        'in dictionary using the control's Tag property
        For Each tBox In controlPanel.Controls
            If Not tBox.Tag Is Nothing AndAlso tBox.Tag.GetType.ToString = "System.String" And tBox.Tag <> "" Then

                Try
                    If TypeOf tBox Is TextBox Then
                        tBox.Text = dict(tBox.Tag).Value
                    ElseIf TypeOf tBox Is CheckBox Then
                        Dim checkBox As CheckBox
                        checkBox = CType(tBox, CheckBox)
                        checkBox.Checked = dict(tBox.Tag).Value
                    Else
                        tBox.Text = dict(tBox.Tag).Value
                    End If

                Catch e As KeyNotFoundException
                    If TypeOf tBox Is CheckBox Then
                        dict.Add(tBox.Tag, New PropertyValue("False", "False"))
                    Else
                        dict.Add(tBox.Tag, New PropertyValue("", "False"))
                        tBox.Text = ""
                    End If

                End Try
            End If
        Next

    End Sub

    Sub UpdateColumnFieldsWithFormValues(ByVal dict As Dictionary(Of String, String))
        Dim tBox As New Control

        'loop through all controls and populate form values with corresponding value stored 
        'in dictionary using the control's Tag property
        For Each tBox In TabPage2.Controls.Item(0).Controls

            If Not tBox.Tag Is Nothing AndAlso tBox.Tag.GetType.ToString = "System.String" Then
                dict(tBox.Tag) = tBox.Text
            End If
        Next

    End Sub

    Private Sub txtTableDescription_TextChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles txtTableDescription.TextChanged
        Dim seltreenode As TreeNode = tvwDatabaseLO.SelectedNode
        seltreenode.Tag.Description = txtTableDescription.Text
        FlagDirty()
    End Sub


    Private Sub cboTables_SelectionChangeCommitted(ByVal sender As Object, ByVal e As System.EventArgs) Handles cboTables.SelectionChangeCommitted
        tgenerateParameters.Values("TableName") = Me.cboTables.SelectedItem
        If Not btnSaveFile.Enabled Then btnSaveFile.Enabled = True
    End Sub


    Private Sub TreeView1_DragDrop(ByVal sender As Object, ByVal e As System.Windows.Forms.DragEventArgs) Handles TreeView1.DragDrop

        DragDropSupport(sender, e, selectedPage)

    End Sub

    Sub DragDropSupport(ByVal sender As Object, ByVal e As System.Windows.Forms.DragEventArgs, ByVal selectedPage As Integer)
        Dim copyNode As Boolean = False
        'Check that there is a TreeNode being dragged
        If e.Data.GetDataPresent("System.Windows.Forms.TreeNode", _
              True) = False Then Exit Sub

        'Get the TreeView raising the event (incase multiple on form)
        Dim selectedTreeview As TreeView = CType(sender, TreeView)

        'Get the TreeNode being dragged
        Dim sourceNode As TreeNode = _
              CType(e.Data.GetData("System.Windows.Forms.TreeNode"), _
              TreeNode)


        If (e.KeyState And 8) = 8 Then
            copyNode = True
        End If

        Dim dropNode As TreeNode, dropObject As Object, sourceNodeLevel As Int32, insertNodes As TreeNodeCollection
        Dim insertIndex As Int32
        sourceNodeLevel = sourceNode.Level
        'if copy node then make copy of source node
        If copyNode Then
            dropNode = sourceNode.Clone
            dropObject = dropNode.Tag.Clone
            dropNode.Tag = dropObject
        Else
            dropNode = sourceNode
            dropObject = dropNode.Tag
        End If

        'The target node should be selected from the DragOver event
        Dim targetNode As TreeNode = selectedTreeview.SelectedNode

        'can't move node to different level
        If (targetNode.Level = 0 Or targetNode.Level <> sourceNodeLevel) AndAlso Not (targetNode.Level = 1 And sourceNodeLevel = 2) Then
            Exit Sub
        End If

        Dim sourceList As Object = Nothing, targetList As Object = Nothing


        'set the node to insert target into
        insertNodes = targetNode.Parent.Nodes

        'determine what the source lists should be depending on the selected node
        If targetNode.Level = 1 Then 'section node
            'if the source is a datatype node then make target list
            If sourceNodeLevel = 2 Then
                If Not copyNode Then sourceList = dropNode.Parent.Tag.DataTypes
                targetList = targetNode.Tag.DataTypes
                insertNodes = targetNode.Nodes
                insertIndex = targetNode.Nodes.Count
            Else
                If Not copyNode Then sourceList = dropNode.Parent.Tag.Sections
                targetList = targetNode.Parent.Tag.Sections
                insertIndex = targetList.IndexOf(targetNode.Tag)
            End If
        Else
            Select Case selectedPage
                Case 0 'datatype node
                    If Not copyNode Then sourceList = dropNode.Parent.Tag.DataTypes
                    targetList = targetNode.Parent.Tag.DataTypes
                Case 1 'columns
                    If Not copyNode Then sourceList = dropNode.Parent.Tag.Columns
                    targetList = targetNode.Parent.Tag.Columns

            End Select
            insertIndex = targetList.IndexOf(targetNode.Tag)
        End If

        'move node?
        If Not copyNode Then
            'Remove the drop node from its current location
            sourceList.Remove(dropNode.Tag)
            dropNode.Remove()
        End If


        'insert node into TreeView and List object
        targetList.Insert(insertIndex, dropObject)
        insertNodes.Insert(targetNode.Index, dropNode)

        dropNode.EnsureVisible()
        selectedTreeview.SelectedNode = dropNode ' 
        FlagDirty()
    End Sub

    Private Sub TreeView1_DragEnter(ByVal sender As Object, ByVal e As System.Windows.Forms.DragEventArgs) Handles TreeView1.DragEnter

        DragEnterSupport(e)

    End Sub

    Sub DragEnterSupport(ByVal e As System.Windows.Forms.DragEventArgs)
        'See if there is a TreeNode being dragged
        If e.Data.GetDataPresent("System.Windows.Forms.TreeNode", _
            True) Then
            'TreeNode found allow move effect
            e.Effect = DragDropEffects.Move
        Else
            'No TreeNode found, prevent move
            e.Effect = DragDropEffects.None
        End If

    End Sub

    Sub DragOverSupport(ByVal sender As Object, ByVal e As System.Windows.Forms.DragEventArgs)
        'Check that there is a TreeNode being dragged 
        If e.Data.GetDataPresent("System.Windows.Forms.TreeNode", _
               True) = False Then Exit Sub

        'Get the TreeView raising the event (incase multiple on form)
        Dim selectedTreeview As TreeView = CType(sender, TreeView)

        'As the mouse moves over nodes, provide feedback to 
        'the user by highlighting the node that is the 
        'current drop target
        Dim pt As Point = _
            CType(sender, TreeView).PointToClient(New Point(e.X, e.Y))
        Dim targetNode As TreeNode = selectedTreeview.GetNodeAt(pt)

        'See if the targetNode is currently selected, 
        'if so no need to validate again
        If Not (selectedTreeview.SelectedNode Is targetNode) Then
            'Select the    node currently under the cursor
            selectedTreeview.SelectedNode = targetNode

            'Check that the selected node is not the dropNode and
            'also that it is not a child of the dropNode and 
            'therefore an invalid target
            Dim dropNode As TreeNode = _
                CType(e.Data.GetData("System.Windows.Forms.TreeNode"), _
                TreeNode)

            If (targetNode.Level = 0 Or targetNode.Level <> dropNode.Level) AndAlso Not (targetNode.Level = 1 And dropNode.Level = 2) Then
                e.Effect = DragDropEffects.None
                Exit Sub
            End If

            Do Until targetNode Is Nothing
                If targetNode Is dropNode Then
                    e.Effect = DragDropEffects.None
                    Exit Sub
                End If
                targetNode = targetNode.Parent
            Loop

            'Currently selected node is a suitable target
            'if Control key pressed then copy mode..
            If ((e.KeyState And 8) = 8) Then
                e.Effect = DragDropEffects.Copy
                Exit Sub
            Else
                e.Effect = DragDropEffects.Move
            End If


        End If

    End Sub
    Private Sub TreeView1_DragOver(ByVal sender As Object, ByVal e As System.Windows.Forms.DragEventArgs) Handles TreeView1.DragOver
        DragOverSupport(sender, e)
    End Sub


    Private Sub TreeView1_ItemDrag(ByVal sender As Object, ByVal e As System.Windows.Forms.ItemDragEventArgs) Handles TreeView1.ItemDrag
        'Set the drag node and initiate the DragDrop 
        DoDragDrop(e.Item, DragDropEffects.Move + DragDropEffects.Copy)
    End Sub



    Private Sub cboDataTypes_SelectionChangeCommitted(ByVal sender As Object, ByVal e As System.EventArgs)
        FlagDirty()
    End Sub

    Private Sub cboFieldType_SelectionChangeCommitted(ByVal sender As Object, ByVal e As System.EventArgs)
        FlagDirty()
    End Sub


    Private Sub btnNewFile_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnNewFile.Click
        Dim newObject As Object
        Dim t As Type = Type.GetType("C3I.CodegenTools." & fileTypes(selectedPage * 3 + 2) & ", C3I.CodegenTools, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null") ' & fileTypes(selectedPage * 3 + 2))

        'if current page is dirty then ask to save first
        If idDirty(selectedPage) Then

        End If

        newObject = Activator.CreateInstance(t)

        newObject.FileName = ""

        idDirty(selectedPage) = False
        pageObjects(selectedPage) = newObject

        'check what type of new item was created and populate tab
        Select Case selectedPage

            Case 0
                CreateTreeView(Me.TreeView1, newObject)
            Case 1
                CreateDBLayoutTreeView(Me.tvwDatabaseLO, newObject)
            Case 2
                tgenerateParameters = newObject
                PopulateGenericFields()
            Case 3

                layoutConfig = newObject
                LoadConfigSettingsFlags()

        End Select

        'flag page as dirty - even though it's not modified yet, still want to be able to save it
        idDirty(selectedPage) = True
        titleBar(selectedPage) = ""
        Me.Text = My.Application.Info.Title
        pageObjects(selectedPage) = newObject
        btnSaveFile.Enabled = True
    End Sub

    Private Sub btnLoadFile_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnLoadFile.Click
        Dim retObject As Object
        Dim a As New C3I.CodegenTools.LayoutTemplate

        'set dialogue filter depending on which tab is selected
        dlgOpenFile.Filter = fileTypes(selectedPage * 3) & "|" & fileTypes(selectedPage * 3 + 1)
        dlgOpenFile.FileName = ""

        If dlgOpenFile.ShowDialog() = Windows.Forms.DialogResult.OK Then

            Windows.Forms.Cursor.Current = System.Windows.Forms.Cursors.WaitCursor

            retObject = Utils.LoadSerializedFile(dlgOpenFile.FileName)

            retObject.FileName = dlgOpenFile.FileName

            'if file successfully loaded populate the appropriate tab
            If Not retObject Is Nothing Then

                Select Case selectedPage

                    Case 0
                        CreateTreeView(Me.TreeView1, retObject)
                    Case 1
                        CreateDBLayoutTreeView(Me.tvwDatabaseLO, retObject)
                    Case 2
                        tgenerateParameters = retObject
                        PopulateGenericFields()
                        Try
                            'open file
                            dbServer = Utils.LoadSerializedFile(tgenerateParameters.Values("DatabaseFile"))

                        Catch ex As Exception
                            MsgBox("Unable to open file" & tgenerateParameters.Values("DatabaseFile") & vbCrLf & ex.Message)
                        End Try

                        If Not dbServer Is Nothing AndAlso Not dbServer.Databases Is Nothing Then
                            PopulateDatabaseList()
                            cboTables.Text = tgenerateParameters.Values("TableName")
                            cboDBs.Text = tgenerateParameters.Values("DatabaseName")
                            PopulateTableList()
                            cboTables.Text = tgenerateParameters.Values("TableName")
                            cboDBs.Text = tgenerateParameters.Values("DatabaseName")
                        End If
                    Case 3
                        layoutConfig = retObject
                        LoadConfigSettingsFlags()
                End Select

                'flag page as not dirty
                idDirty(selectedPage) = False
                pageObjects(selectedPage) = retObject

                RefreshAddDeleteButtons()
                titleBar(selectedPage) = retObject.FileName

                Me.Text = My.Application.Info.Title & " " & retObject.FileName

            End If

            Windows.Forms.Cursor.Current = System.Windows.Forms.Cursors.Default
            btnSaveFile.Enabled = False
        End If


    End Sub

    Private Sub btnSaveFile_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnSaveFile.Click
        Dim pageObject As Object, bSaveFile As Boolean = False

        pageObject = pageObjects(selectedPage)

        If pageObject Is Nothing Then Exit Sub


        'if not file name set yet then new object, show save dialogue
        If pageObject.FileName = "" Then
            'set dialogue filter depending on which tab is selected
            dlgSaveFile.Filter = fileTypes(selectedPage * 3) & "|" & fileTypes(selectedPage * 3 + 1)
            dlgSaveFile.FileName = pageObject.FileName
            If dlgSaveFile.ShowDialog() = Windows.Forms.DialogResult.OK Then
                bSaveFile = True
                pageObject.filename = dlgSaveFile.FileName
            End If

        Else
            bSaveFile = True
        End If


        If bSaveFile Then
            Windows.Forms.Cursor.Current = System.Windows.Forms.Cursors.WaitCursor

            If selectedPage = 2 Then
                UpdateGenericFieldsWithFormValues()
            End If

            Utils.SaveFile(pageObject.filename, pageObject)

            'flag page as not dirty and disabled Save button
            idDirty(selectedPage) = False
            btnSaveFile.Enabled = False

            Me.Text = My.Application.Info.Title & " " & pageObject.FileName
            Windows.Forms.Cursor.Current = System.Windows.Forms.Cursors.Default

        End If

    End Sub

    Private Sub btnAddNewItem_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnAddNewItem.Click
        Dim templatelayout As LayoutTemplate
        Dim seltreenode As TreeNode, newNode As New TreeNode


        Select Case selectedPage
            Case 0
                Dim sectionTemplate As New SectionTemplate

                seltreenode = TreeView1.SelectedNode
                If selectedLevel = 0 Then
                    templatelayout = seltreenode.Tag
                    sectionTemplate.Description = "New Section"

                    templatelayout.Sections.Add(sectionTemplate)

                    newNode.Tag = sectionTemplate
                    newNode.Text = "New Section"
                    newNode.Name = "sec_New Section"
                    newNode.ImageKey = "section"
                    newNode.SelectedImageKey = "section"
                    seltreenode.Nodes.Add(newNode)
                Else
                    Dim detaillayout As New DataType
                    sectionTemplate = seltreenode.Tag

                    detaillayout.Description = "New Datatype"
                    detaillayout.Type = "Any Data Type"
                    detaillayout.FieldName = "(none)"
                    detaillayout.FieldType = "All fields"
                    newNode.Tag = detaillayout
                    newNode.Text = "New Datatype"
                    newNode.Name = "det_New datatype"
                    newNode.ImageKey = "script"
                    newNode.SelectedImageKey = "script"

                    seltreenode.Nodes.Add(newNode)
                    sectionTemplate.DataTypes.Add(detaillayout)

                End If

            Case 1 'database page
                seltreenode = tvwDatabaseLO.SelectedNode
                Dim sectionTemplate As New SectionTemplate, databaseTable As TableLayout, tableColumn As New Column

                databaseTable = seltreenode.Tag
                tableColumn.Name = "New Virtual Field"
                tableColumn.GenericType = "String"

                tableColumn.IsVirtualField = True
                databaseTable.Columns.Add(tableColumn)

                newNode.Tag = tableColumn
                newNode.Text = tableColumn.Name
                newNode.Name = "col_NewField"
                newNode.ImageKey = "section"
                newNode.SelectedImageKey = "section"
                seltreenode.Nodes.Add(newNode)

        End Select

        FlagDirty()

    End Sub

    Private Sub btnDeleteItem_Click_1(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnDeleteItem.Click
        Dim seltreenode As TreeNode
        Dim sectionTemplate As New SectionTemplate
        Dim templatelayout As LayoutTemplate

        Select Case selectedPage
            Case 0
                seltreenode = TreeView1.SelectedNode
                If selectedLevel = 1 Then
                    'get the section from the parent node
                    templatelayout = seltreenode.Parent.Tag

                    'get selected section template object
                    sectionTemplate = seltreenode.Tag

                    'remove section template object and node
                    templatelayout.Sections.Remove(sectionTemplate)
                    seltreenode.Remove()
                Else
                    Dim detaillayout As New DataType

                    'get the section from the parent node
                    sectionTemplate = seltreenode.Parent.Tag

                    '
                    detaillayout = seltreenode.Tag

                    sectionTemplate.DataTypes.Remove(detaillayout)
                    seltreenode.Remove()
                End If

            Case 1
                Dim tableLayout As TableLayout

                seltreenode = tvwDatabaseLO.SelectedNode
                tableLayout = seltreenode.Parent.Tag

                tableLayout.Columns.Remove(seltreenode.Tag)
                seltreenode.Remove()
        End Select

        FlagDirty()

    End Sub


    Private Sub cboDatabaseType_SelectedIndexChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles cboDatabaseType.SelectedIndexChanged
        tvwDatabaseLO.SelectedNode.Tag.DatabaseType = cboDatabaseType.Text
        FlagDirty()
    End Sub



    Private Sub DataGridView1_EditingControlShowing(ByVal sender As Object, ByVal e As System.Windows.Forms.DataGridViewEditingControlShowingEventArgs)
        Dim cb As ComboBox = CType(e.Control, ComboBox)

        If Not cb Is Nothing Then
            cb.DropDownStyle = ComboBoxStyle.DropDown
        End If
    End Sub

    Private Sub txtGenerate_TextChanged(ByVal sender As System.Object, ByVal e As System.EventArgs)
        FlagDirty()
    End Sub


    Private Sub dgvSecConditions_CellValidating(ByVal sender As Object, ByVal e As System.Windows.Forms.DataGridViewCellValidatingEventArgs) Handles dgvSecConditions.CellValidating
        If e.ColumnIndex = 0 Then

            Dim cb As DataGridViewComboBoxColumn = dgvSecConditions.Columns(0)

            If Not cb.Items.Contains(e.FormattedValue) And e.FormattedValue <> "" Then
                cb.Items.Add(e.FormattedValue)
                dgvSecConditions.CurrentCell.Value = e.FormattedValue
            End If
        End If
    End Sub


    Private Sub dgvSecConditions_EditingControlShowing(ByVal sender As Object, ByVal e As System.Windows.Forms.DataGridViewEditingControlShowingEventArgs) Handles dgvSecConditions.EditingControlShowing
        If dgvSecConditions.CurrentCellAddress.X = 0 Then
            Dim cb As ComboBox = e.Control

            If Not cb Is Nothing Then
                cb.DropDownStyle = ComboBoxStyle.DropDown
            End If
        End If
    End Sub


    Private Sub chkFlag_CheckedChanged(ByVal sender As System.Object, ByVal e As System.EventArgs)
        tvwDatabaseLO.SelectedNode.Tag.Properties(sender.Tag).Value = sender.Checked.ToString
        FlagDirty()
    End Sub

    Private Sub txtTableTextChanged_TextChanged(ByVal sender As System.Object, ByVal e As System.EventArgs)
        tvwDatabaseLO.SelectedNode.Tag.Properties(sender.Tag).Value = sender.Text
        FlagDirty()
    End Sub

    Private Sub chkFieldFlag_CheckedChanged(ByVal sender As System.Object, ByVal e As System.EventArgs)
        tvwDatabaseLO.SelectedNode.Tag.Values(sender.Tag).Value = sender.Checked.ToString
        FlagDirty()
    End Sub

    Private Sub txtDataSourceName_TextChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles txtDataSourceName.TextChanged
        tvwDatabaseLO.SelectedNode.Tag.DataSourceName = txtDataSourceName.Text
        FlagDirty()
    End Sub

    Private Sub txtFieldTextChanged_TextChanged(ByVal sender As System.Object, ByVal e As System.EventArgs)
        tvwDatabaseLO.SelectedNode.Tag.Values(sender.Tag).Value = sender.Text
        FlagDirty()
    End Sub


    Private Sub txtDBConnectionString_TextChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles txtDBConnectionString.TextChanged
        tvwDatabaseLO.SelectedNode.Tag.ConnectionString = txtDBConnectionString.Text
        FlagDirty()
    End Sub

    Private Sub chkDirectFKSQLStatement_CheckedChanged(ByVal sender As System.Object, ByVal e As System.EventArgs)
        tvwDatabaseLO.SelectedNode.Tag.Values("FKDirectStatement") = chkFlag1.Checked.ToString
        FlagDirty()
    End Sub

    Private Sub tvwDatabaseLO_DragDrop(ByVal sender As Object, ByVal e As System.Windows.Forms.DragEventArgs) Handles tvwDatabaseLO.DragDrop
        DragDropSupport(sender, e, selectedPage)
    End Sub

    Private Sub tvwDatabaseLO_DragEnter(ByVal sender As Object, ByVal e As System.Windows.Forms.DragEventArgs) Handles tvwDatabaseLO.DragEnter
        DragEnterSupport(e)
    End Sub

    Private Sub tvwDatabaseLO_DragOver(ByVal sender As Object, ByVal e As System.Windows.Forms.DragEventArgs) Handles tvwDatabaseLO.DragOver
        DragOverSupport(sender, e)
    End Sub

    Private Sub tvwDatabaseLO_ItemDrag(ByVal sender As Object, ByVal e As System.Windows.Forms.ItemDragEventArgs) Handles tvwDatabaseLO.ItemDrag
        'Set the drag node and initiate the DragDrop 
        DoDragDrop(e.Item, DragDropEffects.Move + DragDropEffects.Copy)
    End Sub

    Private Sub txtFlagLabel_TextChanged(ByVal sender As System.Object, ByVal e As System.EventArgs)
        layoutConfig.PairValues(sender.Tag)(0) = sender.Text
        FlagDirty()
    End Sub

    Private Sub txtFlagDescription_TextChanged(ByVal sender As System.Object, ByVal e As System.EventArgs)
        layoutConfig.PairValues(sender.Tag)(1) = sender.Text
        FlagDirty()
    End Sub

    Private Sub txtMessage1_TextChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles txtMessage1.TextChanged
        layoutConfig.PairValues(sender.Tag)(1) = sender.Text
        FlagDirty()
    End Sub

    Private Sub cboAssociationType_SelectedIndexChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles cboAssociationType.SelectedIndexChanged
        tvwDatabaseLO.SelectedNode.Tag.Values(sender.Tag).Value = sender.Text
        FlagDirty()
    End Sub

    Private Sub txtFieldName_TextChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles txtFieldName.TextChanged
        tvwDatabaseLO.SelectedNode.Tag.Name = txtFieldName.Text
        tvwDatabaseLO.SelectedNode.Text = txtFieldName.Text
        FlagDirty()
    End Sub



    Private Sub txtDetailTemplate_TextChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles txtDetailTemplate.TextChanged
        Dim seltreenode As TreeNode = TreeView1.SelectedNode
        seltreenode.Tag.Template = txtDetailTemplate.Text
        FlagDirty()

    End Sub

    Private Sub txtDetailTemplate_Enter(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles txtDetailTemplate.Enter
        selectedControl = txtDetailTemplate
        listProperties.Visible = True
        Me.Select()

    End Sub

    Private Sub txtDetailTemplate_Leave(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles txtDetailTemplate.Leave
        selectedControl = Nothing
        listProperties.Visible = False
        Me.Select()

    End Sub

    Private Sub cboDataTypes_SelectedIndexChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles cboDataTypes.SelectedIndexChanged
        TreeView1.SelectedNode.Tag.Type = cboDataTypes.Text
        FlagDirty()
    End Sub


    Private Sub cboFieldType_SelectedIndexChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles cboFieldType.SelectedIndexChanged
        TreeView1.SelectedNode.Tag.FieldType = cboFieldType.Text
        FlagDirty()

    End Sub

    Private Sub txtDetailType_TextChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles txtDetailType.TextChanged
        TreeView1.SelectedNode.Tag.Description = txtDetailType.Text
        TreeView1.SelectedNode.Text = txtDetailType.Text
        FlagDirty()

    End Sub

    Private Sub cboNextStep_SelectedIndexChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles cboNextStep.SelectedIndexChanged
        TreeView1.SelectedNode.Tag.NextStep = cboNextStep.SelectedIndex
        FlagDirty()
    End Sub

    Private Sub cboLevel_SelectedIndexChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles cboLevel.SelectedIndexChanged
        TreeView1.SelectedNode.Tag.Level = Int16.Parse(cboLevel.Text)
        FlagDirty()
    End Sub


    Private Sub chkOr_CheckedChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles chkOr.CheckedChanged
        TreeView1.SelectedNode.Tag.OrField = chkOr.Checked
        FlagDirty()
    End Sub


    Private Sub dgvConditions_CellValidating(ByVal sender As Object, ByVal e As System.Windows.Forms.DataGridViewCellValidatingEventArgs) Handles dgvConditions.CellValidating

        If e.ColumnIndex = 0 Then

            Dim cb As DataGridViewComboBoxColumn = dgvConditions.Columns(0)

            If Not cb.Items.Contains(e.FormattedValue) And e.FormattedValue <> "" Then
                cb.Items.Add(e.FormattedValue)
                dgvConditions.CurrentCell.Value = e.FormattedValue
            End If
        End If
    End Sub

    Private Sub dgvConditions_EditingControlShowing(ByVal sender As Object, ByVal e As System.Windows.Forms.DataGridViewEditingControlShowingEventArgs) Handles dgvConditions.EditingControlShowing

        If dgvConditions.CurrentCellAddress.X = 0 Then
            Dim cb As ComboBox = e.Control

            If Not cb Is Nothing Then
                cb.DropDownStyle = ComboBoxStyle.DropDown
            End If
        End If

    End Sub

    Private Sub dgvConditions_DataError(ByVal sender As System.Object, ByVal e As System.Windows.Forms.DataGridViewDataErrorEventArgs) Handles dgvConditions.DataError
        Dim oCol As DataGridViewComboBoxColumn
        oCol = dgvConditions.Columns(0)
        'add value to drop down if doesn't exist
        oCol.Items.Add(sender.Rows(e.RowIndex).Cells(e.ColumnIndex).Value)

    End Sub

    Private Sub cboProcessWhat_SelectedIndexChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles cboProcessWhat.SelectedIndexChanged

        'Single Table or View
        If cboProcessWhat.Text = "Single Table or View" Then
            cboTables.Enabled = True
        Else
            cboTables.Enabled = False
        End If
        FlagDirty()

    End Sub

    Private Sub dgvConditions_UserAddedRow(ByVal sender As Object, ByVal e As System.Windows.Forms.DataGridViewRowEventArgs) Handles dgvConditions.UserAddedRow
        dgvConditions.Rows(e.Row.Index - 1).Cells(1).Value = "Equals (=)"
    End Sub

    Private Sub chkIsEmpty_CheckedChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles chkIsEmpty.CheckedChanged
        TreeView1.SelectedNode.Tag.EmptyField = chkIsEmpty.Checked
        txtDetailTemplate.Visible = Not chkIsEmpty.Checked
        lblTemplate.Visible = Not chkIsEmpty.Checked
        FlagDirty()
    End Sub

    Private Sub dgvConditions_CellValueChanged(ByVal sender As Object, ByVal e As System.Windows.Forms.DataGridViewCellEventArgs) Handles dgvConditions.CellValueChanged
        FlagDirty()
    End Sub
    ''' <summary>
    ''' 
    ''' </summary>
    ''' <param name="sender"></param>
    ''' <param name="e"></param>
    ''' <remarks></remarks>

    Private Sub valsgrid_CellBeginEdit(ByVal sender As Object, ByVal e As System.Windows.Forms.DataGridViewCellCancelEventArgs) Handles valsgrid.CellBeginEdit
        Dim currentCell As DataGridViewCell = valsgrid.CurrentCell

        isNewRow = currentCell.OwningRow.IsNewRow

        'prevent editing of property name, only allow property name changes for new columns
        If Not isNewRow And currentCell.ColumnIndex = 0 Then
            e.Cancel = True
            MsgBox("Can't Edit Property name. To change property name, delete row and add using new name")
            Exit Sub
        End If

        'prevent editing of property value if new row and no new property name entered  yet
        If isNewRow And currentCell.ColumnIndex = 1 And (currentCell.OwningRow.Cells(0).Value Is Nothing OrElse Not currentCell.OwningRow.Cells(0).Value.ToString = "") Then
            e.Cancel = True
            MsgBox("Can't Edit Property value until name set for new property. ")
            Exit Sub
        End If

        originalValue = currentCell.Value

    End Sub

    Private Sub valsgrid_CellContentClick(ByVal sender As System.Object, ByVal e As System.Windows.Forms.DataGridViewCellEventArgs) Handles valsgrid.CellContentClick

    End Sub


    Private Sub valsgrid_CellValidating(ByVal sender As Object, ByVal e As System.Windows.Forms.DataGridViewCellValidatingEventArgs) Handles valsgrid.CellValidating
        Dim currentCell As DataGridViewCell = valsgrid.CurrentCell
        Dim a As DataGridView = sender

        'make sure property doesn't already exist
        If currentCell.ColumnIndex = 0 And sender.IsCurrentCellDirty AndAlso Not currentCell.EditedFormattedValue Is Nothing AndAlso columnDictionary.ContainsKey(currentCell.EditedFormattedValue) Then

            e.Cancel = True
            sender.CancelEdit()
            MsgBox("Property already exists")

            'if blank cell then cancel edit
        ElseIf sender.IsCurrentCellDirty AndAlso Not currentCell.EditedFormattedValue Is Nothing And currentCell.EditedFormattedValue = "" Then
            sender.CancelEdit()
        Else

            'make sure row values have changed and is not a blank value
            If valsgrid.IsCurrentRowDirty And Not currentCell.EditedFormattedValue Is Nothing Then
                'if not new row then update property value
                If Not isNewRow Then
                    columnDictionary(currentCell.OwningRow.Cells(0).Value).Value = currentCell.EditedFormattedValue
                Else ' otherwise add new property
                    columnDictionary.Add(currentCell.EditedFormattedValue, New PropertyValue("", False))
                End If
            End If

        End If

    End Sub

    Private Sub valsgrid_UserDeletingRow(ByVal sender As Object, ByVal e As System.Windows.Forms.DataGridViewRowCancelEventArgs) Handles valsgrid.UserDeletingRow
        Dim currentRow As DataGridViewRow = valsgrid.CurrentRow

        'if not in edit mode (which indicates a cancelled cell change) remove item from dictionary
        If Not sender.IsCurrentCellInEditMode Then
            columnDictionary.Remove(currentRow.Cells(0).Value)
        End If
    End Sub

    Private Sub chkIgnore_CheckedChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles chkIgnore.CheckedChanged
        tvwDatabaseLO.SelectedNode.Tag.Ignore = chkIgnore.Checked
    End Sub

    Private Sub txtRootPostTemplate_TextChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles txtRootPostTemplate.TextChanged
        TreeView1.SelectedNode.Tag.PostfixTemplate = Me.txtRootPostTemplate.Text
        FlagDirty()
    End Sub

    Private Sub cboDBs_SelectedIndexChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles cboDBs.SelectedIndexChanged
        FlagDirty()
    End Sub

    Private Sub txtRootPreTemplate_Enter(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles txtRootPreTemplate.Enter
        selectedControl = txtRootPreTemplate
        listProperties.Visible = True
        Me.Select()
    End Sub

    Private Sub txtRootPreTemplate_Leave(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles txtRootPreTemplate.Leave
        selectedControl = Nothing
        listProperties.Visible = False
    End Sub

    Private Sub txtRootPreTemplate_TextChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles txtRootPreTemplate.TextChanged
        TreeView1.SelectedNode.Tag.PrefixTemplate = Me.txtRootPreTemplate.Text
        FlagDirty()
    End Sub

    Private Sub txtRootPostTemplate_Leave(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles txtRootPostTemplate.Leave
        selectedControl = Nothing
        listProperties.Visible = False
    End Sub

    Private Sub txtRootPostTemplate_Enter(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles txtRootPostTemplate.Enter
        selectedControl = txtRootPostTemplate
        listProperties.Visible = True
        Me.Select()
    End Sub

    Private Sub txtRootDescription_TextChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles txtRootDescription.TextChanged
        TreeView1.SelectedNode.Tag.LayoutName = Me.txtRootDescription.Text
        TreeView1.SelectedNode.Text = txtRootDescription.Text
        FlagDirty()
    End Sub

    Private Sub dgv_RowsAdded(ByVal sender As System.Object, ByVal e As System.Windows.Forms.DataGridViewRowsAddedEventArgs)
        If e.RowIndex > 0 And sender.iscurrentrowdirty Then
            dgvConditions.Rows(e.RowIndex).Cells(1).Value = "Equals (=)"
        End If
    End Sub
    'dgvFieldFunctions

    Private Sub dgvSecConditions_UserAddedRow(ByVal sender As System.Object, ByVal e As System.Windows.Forms.DataGridViewRowEventArgs) Handles dgvSecConditions.UserAddedRow
        dgvSecConditions.Rows(e.Row.Index - 1).Cells(1).Value = "Equals (=)"
        FlagDirty()
    End Sub

    Private Sub dgvPropCustom_CausesValidationChanged(ByVal sender As Object, ByVal e As System.EventArgs) Handles dgvPropCustom.CausesValidationChanged
        FlagDirty()
    End Sub

    Private Sub dgvPropCustom_UserAddedRow(ByVal sender As Object, ByVal e As System.Windows.Forms.DataGridViewRowEventArgs) Handles dgvPropCustom.UserAddedRow
        FlagDirty()
    End Sub
  
    Private Sub txtServerPort_TextChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles txtServerPort.TextChanged
        tvwDatabaseLO.SelectedNode.Tag.Port = txtServerPort.Text
        FlagDirty()
    End Sub

    Private Sub dgvPropCustom_CellContentClick(ByVal sender As System.Object, ByVal e As System.Windows.Forms.DataGridViewCellEventArgs) Handles dgvPropCustom.CellContentClick

    End Sub

    Private Sub dgvPropCustom_Validating(ByVal sender As Object, ByVal e As System.ComponentModel.CancelEventArgs) Handles dgvPropCustom.Validating
        FlagDirty()
    End Sub

    Private Sub dgvPropCustom_CellEndEdit(ByVal sender As Object, ByVal e As System.Windows.Forms.DataGridViewCellEventArgs) Handles dgvPropCustom.CellEndEdit
        If oldValue <> sender.CurrentCell.Value Then
            FlagDirty()
        End If
    End Sub

    Private Sub dgvPropCustom_CellBeginEdit(ByVal sender As Object, ByVal e As System.Windows.Forms.DataGridViewCellCancelEventArgs) Handles dgvPropCustom.CellBeginEdit
        oldValue = sender.CurrentCell.Value
    End Sub

    Private Sub dgvFieldFunctions_RowsAdded(ByVal sender As Object, ByVal e As System.Windows.Forms.DataGridViewRowsAddedEventArgs) Handles dgvFieldFunctions.RowsAdded
        'set default values
        If e.RowIndex > 0 And sender.iscurrentrowdirty Then
            dgvFieldFunctions.Rows(e.RowIndex - 1).Cells(2).Value = "Field"
            dgvFieldFunctions.Rows(e.RowIndex - 1).Cells(3).Value = "New only"
        End If
    End Sub
End Class
